#region File Description
//-----------------------------------------------------------------------------
// GameplayScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using System.Threading;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
//using Microsoft.Xna.Framework.Content;
using GuildofHeroes;

#endregion

namespace GameStateManagement
{
    /// <summary>
    /// This screen implements the actual game logic. It is just a
    /// placeholder to get the idea across: you'll probably want to
    /// put some more interesting gameplay in here!
    /// </summary>
    /// public void LoadClassWarrior()
            
    class GameplayScreen : GameScreen
    {
        #region Fields

        ContentManager content;
        SpriteFont gameFont;        

        public enum PlayerClass
        {
            Warrior,
            Mage,
        }

        bool init = true;
        public PlayerClass CurrentClass;

        public void ClassSelection()
        {
            if (init)
            {
                if (OptionsMenuScreen.CurrentClass == OptionsMenuScreen.Class.Warrior)
                {
                    CurrentClass = PlayerClass.Warrior;
                }
                else if (OptionsMenuScreen.CurrentClass == OptionsMenuScreen.Class.Mage)
                {
                    CurrentClass = PlayerClass.Mage;
                }
            }

            switch (CurrentClass)
            {
                case PlayerClass.Warrior:
                    _player = new Warrior(content.Load<Texture2D>("Hero"), 495, 460, 1, 24, 35, 0, 0, 1, 1);
                    break;
                case PlayerClass.Mage:
                    _player = new Mage(content.Load<Texture2D>("Mage"), 495, 460, 1, 24, 35, 0, 0, 1, 1);
                    break;
            }                
        }

        Vector2 playerPosition = new Vector2(100, 100);
        Vector2 enemyPosition = new Vector2(100, 100);
        public List<Skeleton> SkellyList = new List<Skeleton>();

        //settings
        float timeToNewEnemy = 1f;
        float enemiesPerSecond = 1f;

        Random random = new Random();

        float pauseAlpha;

        #endregion

        public Mage _Mage;
        public Player _player;
        public HomeTown _hometown;
        public Texture2D backgroundTexture;        
        public Texture2D skeleton1Texture;        

        //Rectangles
        public Rectangle backgroundRectangle;

        #region Initialization

        /// <summary>
        /// Constructor.
        /// </summary>
        public GameplayScreen()
        {
            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);
        }

        /// <summary>
        /// Load graphics content for the game.
        /// </summary>
        public override void LoadContent()
        {
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");

            gameFont = content.Load<SpriteFont>("gamefont");
            backgroundTexture = content.Load<Texture2D>("gameBackground");
            skeleton1Texture = content.Load<Texture2D>("Skeleton1");

            //Sound for the game 
            //options for slecting class

            ClassSelection();          

            _hometown = new HomeTown(content.Load<Texture2D>("HomeTown"), 500, 385, 1, 100, 100, 0, 0, 1, 1);
            //SkellyList.Add(new Skeleton(content.Load<Texture2D>("Skeleton1"), 20, 20, 1, 39, 34, 0, 0, 1, 1));

            // A real game would probably have more content than this sample, so
            // it would take longer to load. We simulate that by delaying for a
            // while, giving you a chance to admire the beautiful loading screen.
            Thread.Sleep(1000);

            // once the load has finished, we use ResetElapsedTime to tell the game's
            // timing mechanism that we have just finished a very long frame, and that
            // it should not try to catch up.
            ScreenManager.Game.ResetElapsedTime();
            
        }

        /// <summary>
        /// Unload graphics content used by the game.
        /// </summary>
        public override void UnloadContent()
        {
            content.Unload();
        }        

        #endregion

        #region Update and Draw

        /// <summary>
        /// Updates the state of the game. This method checks the GameScreen.IsActive
        /// property, so the game will stop updating when the pause menu is active,
        /// or if you tab away to a different application.
        /// </summary>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                       bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);
            float timeStep = (float)gameTime.ElapsedGameTime.TotalSeconds;

            // Gradually fade in or out depending on whether we are covered by the pause screen.
            if (coveredByOtherScreen)
                pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1);
            else
                pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0);             

            if (IsActive)
            {
                KeyboardState keyboard = Keyboard.GetState();
                MouseState mouse = Mouse.GetState();

                if (mouse.LeftButton == ButtonState.Pressed)
                {
                    _player.UpdatePos(mouse.X, mouse.Y);
                }

                _player.CheckMovement(keyboard);
                _player.Update(gameTime, keyboard);

                foreach (Skeleton skelly in SkellyList)
                {
                    skelly.Update(gameTime, _player.Position(), _hometown.Position());
                }

                foreach (Skeleton skelly in SkellyList)
                {
                    if ((skelly.GetX() - (skelly.GetWidth() / 2)) < (_player.GetPosX() + (_player.GetWidth() / 2)) &&
                        (skelly.GetX() + (skelly.GetWidth() / 2)) > (_player.GetPosX() - (_player.GetWidth() / 2)) &&
                        (skelly.GetY() - (skelly.GetWidth() / 2)) < (_player.GetPosY() + (_player.GetHeight() / 2)) &&
                        (skelly.GetY() + (skelly.GetWidth() / 2)) > (_player.GetPosY() - (_player.GetHeight() / 2)))
                    {
                        _player.UpdateHealth(true, skelly.GetDamage());
                        skelly.UpdateHealth(true, _player.GetDamage());
                        skelly.Stop();
                        if (!skelly.isAlive())
                        {
                            _player.UpdateGold(skelly.GetGold());
                            _player.UpdateExperience(skelly.GetExp());
                            SkellyList.Remove(skelly);
                            break;
                        }
                    }
                    else if(!skelly.isMoving())
                    {
                        skelly.Start();
                    }

                    if ((skelly.GetX() - (skelly.GetWidth() / 2)) < (_hometown.GetPosX() + (_hometown.GetWidth() / 2)) &&
                        (skelly.GetX() + (skelly.GetWidth() / 2)) > (_hometown.GetPosX() - (_hometown.GetWidth() / 2)) &&
                        (skelly.GetY() - (skelly.GetWidth() / 2)) < (_hometown.GetPosY() + (_hometown.GetHeight() / 2)) &&
                        (skelly.GetY() + (skelly.GetWidth() / 2)) > (_hometown.GetPosY() - (_hometown.GetHeight() / 2)))
                        {
                            _hometown.UpdateHealth(true, skelly.GetDamage());
                            skelly.Stop();
                        }
                }
            
                if (_hometown.isIntact())
                {
                    _hometown.Update(gameTime, keyboard);
                }

                if (_player.isAlive())
                {
                    ClassSelection();
                }
                timeToNewEnemy -= timeStep;
                while (timeToNewEnemy <= 0)
                {
                    float _VelX, _VelY;
                    int _X, _Y;

                    _X = (int)random.Next(0, Game1.ScreenWidth);
                    _Y = (int)random.Next(0, Game1.ScreenHeight);
                    _VelX = (float)random.NextDouble();
                    _VelY = (float)random.NextDouble();


                    if (random.Next() % 2 == 0)
                    {
                        if (_Y > (Game1.ScreenHeight / 2))
                            _Y += (Game1.ScreenHeight / 2);
                        else
                            _Y -= (Game1.ScreenHeight / 2);
                    }
                    else
                    {
                        if (_X > (Game1.ScreenWidth / 2))
                            _X += (Game1.ScreenWidth / 2);
                        else
                            _X -= (Game1.ScreenWidth / 2);
                    }

                    SkellyList.Add(new Skeleton(skeleton1Texture, new Vector2(_VelX, _VelY), _X, _Y, 1, 39, 34, 0, 0, 1, 1));
                    timeToNewEnemy += 5f / enemiesPerSecond;
                    enemiesPerSecond += 0.015f;
                }

                if (_player.isAlive())
                {
                    ClassSelection();
                }

                if (!_hometown.isIntact())
                {
                    ScreenManager.AddScreen(new MainMenuScreen(), null);
                }

            }
        }

        /// <summary>
        /// Lets the game respond to player input. Unlike the Update method,
        /// this will only be called when the gameplay screen is active.
        /// </summary>
        public override void HandleInput(InputState input)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            // Look up inputs for the active player profile.
            int playerIndex = (int)ControllingPlayer.Value;

            KeyboardState keyboardState = input.CurrentKeyboardStates[playerIndex];
            GamePadState gamePadState = input.CurrentGamePadStates[playerIndex];

            // The game pauses either if the user presses the pause button, or if
            // they unplug the active gamepad. This requires us to keep track of
            // whether a gamepad was ever plugged in, because we don't want to pause
            // on PC if they are playing with a keyboard and have no gamepad at all!
            bool gamePadDisconnected = !gamePadState.IsConnected &&
                                       input.GamePadWasConnected[playerIndex];

            if (input.IsPauseGame(ControllingPlayer) || gamePadDisconnected)
            {
                ScreenManager.AddScreen(new PauseMenuScreen(), ControllingPlayer);
            }
            else
            {
                // Otherwise move the player position.
                Vector2 movement = Vector2.Zero;

                if (keyboardState.IsKeyDown(Keys.Left))
                    movement.X--;

                if (keyboardState.IsKeyDown(Keys.Right))
                    movement.X++;

                if (keyboardState.IsKeyDown(Keys.Up))
                    movement.Y--;

                if (keyboardState.IsKeyDown(Keys.Down))
                    movement.Y++;

                Vector2 thumbstick = gamePadState.ThumbSticks.Left;

                movement.X += thumbstick.X;
                movement.Y -= thumbstick.Y;

                if (movement.Length() > 1)
                    movement.Normalize();

                playerPosition += movement * 2;
            }
            
        }


        /// <summary>
        /// Draws the gameplay screen.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            // This game has a blue background. Why? Because!
            ScreenManager.GraphicsDevice.Clear(ClearOptions.Target,
                                               Color.CornflowerBlue, 0, 0);

            // Our player and enemy are both actually just text strings.
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
            backgroundRectangle = new Rectangle(
                0, 0, //top left-hand corner
                this.ScreenManager.GraphicsDevice.Viewport.Width,
                this.ScreenManager.GraphicsDevice.Viewport.Height);

            spriteBatch.Begin();
            spriteBatch.Draw(backgroundTexture, backgroundRectangle, Color.White);            
            _player.Draw(spriteBatch);

            if (_hometown.isIntact())
            {
                _hometown.Draw(spriteBatch);
            }

            foreach (Skeleton skelly in SkellyList)
            {
                skelly.Draw(spriteBatch);
            }

            _player.Draw(spriteBatch, gameFont);

            spriteBatch.DrawString(gameFont, "Base Health: " +  _hometown.GetHealth().ToString(), new Vector2(20, 70), Color.White); 
         
            spriteBatch.End();

            // If the game is transitioning on or off, fade it out to black.
            if (TransitionPosition > 0 || pauseAlpha > 0)
            {
                float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2);

                ScreenManager.FadeBackBufferToBlack(alpha);
            }
        }


        #endregion
    }
}
